import requests
import pandas as pd
import json
import os
from datetime import datetime
import pymysql
from pandas import ExcelWriter
import openpyxl
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side


def get_api_data(url="http://127.0.0.1:6666/api/public/stock_comment_em"):
    """
    从API获取股票历史新高数据
    参数:
        url: API地址，默认为历史新高数据接口
    返回:
        处理后的JSON数据和股票代码列表
    """
    try:
        print(f"正在从API获取数据: {url}")
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功

        data = response.json()
        print(f"成功获取数据，共 {len(data)} 条记录")

        # 提取股票代码
        stock_codes = [item['代码'] for item in data if '代码' in item]
        print(f"提取到 {len(stock_codes)} 个股票代码")

        return data, stock_codes
    except Exception as e:
        print(f"获取API数据失败: {e}")
        return [], []


def get_stock_details(stock_codes, db_config=None):
    """
    从数据库查询股票详细信息
    参数:
        stock_codes: 股票代码列表
        db_config: 数据库连接配置，如果为None则使用默认配置
    返回:
        字典，键为股票代码，值为对应的详细信息
    """
    if not stock_codes:
        print("没有股票代码，跳过数据库查询")
        return {}

    # 数据库连接参数，与zjlx.py保持一致
    default_db_config = {
        'host': '175.178.5.14',
        'port': 33066,
        'user': 'root',
        'password': '07M@Y0sqL1',
        'database': 'stock',
        'charset': 'utf8mb4',
        'connect_timeout': 10
    }

    # 如果提供了自定义配置，则使用自定义配置
    if db_config:
        for key, value in db_config.items():
            if value:  # 只更新非空值
                default_db_config[key] = value

    db_config = default_db_config

    # 构建SQL查询中的IN子句
    codes_str = ', '.join([f"'{code}'" for code in stock_codes])

    # 构建完整的SQL查询，使用您提供的SQL语句
    sql = f"""
        SELECT
            spld.SYMBOL as '股票代码',
            spld.NAME AS '名称',
            ROUND(spld.TOTAL_MARKET_CAP / 100000000, 2)as '市值(亿)',
    --         spld.TURNOVER AS '成交额(亿)',
    --         spld.VOLUME_RATIO AS '量比',
            spld.PE_DYNAMIC AS '市盈率(动)',
            ROUND(smdi.profit_yoy ,2) as '净利润同比(%)',
    --         spld.CHANGE_RATE AS '涨跌幅(%)',
            ROUND(spld.CLOSE_PRICE /spdi.MAX_PRICE,2) as '历史位置',
            spld.YTD_CHG AS '年度涨幅(%)',
            s.SECTOR_NAME AS '行业板块'
        FROM stock_personal_latest_data spld
        LEFT JOIN stock_sector_personal ssp ON spld.ID = ssp.PERSONAL_ID
        LEFT JOIN stock_sector_last_data s ON ssp.SECTOR_ID = s.ID
        LEFT JOIN stock_money_data_info smdi ON spld.SYMBOL = smdi.stock_code
        left join stock_personal_data_info spdi on spld.symbol=spdi.symbol
        where
            spld.SYMBOL in ({codes_str})
            and s.SECTOR_TYPE = '2'
            AND smdi.money_date ='2025-09-30'

        GROUP BY spld.symbol
        ORDER BY s.SECTOR_NAME DESC
        """

    print(f"执行SQL查询: {sql}")

    # 连接数据库并执行查询（参考zjlx.py中的实现）
    stock_details = {}
    try:
        print("尝试连接数据库...")
        conn = pymysql.connect(**db_config)
        print("数据库连接成功")

        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            print("执行SQL查询...")
            cursor.execute(sql)
            results = cursor.fetchall()
            print(f"查询结果: {len(results)} 条记录")

            # 打印查询结果示例

            for result in results:
                stock_code = result['股票代码']
                stock_details[stock_code] = result
                print(f"股票 {stock_code} 的详细信息已获取")
    except pymysql.err.OperationalError as e:
        print(f"数据库连接失败: {e}")
        print("将继续处理数据，但不包含详细信息")
    except Exception as e:
        print(f"数据库查询失败: {e}")
        print("将继续处理数据，但不包含详细信息")
    finally:
        if 'conn' in locals() and conn:
            conn.close()
            print("数据库连接已关闭")

    return stock_details


def merge_data(api_data, stock_details):
    """合并API数据和数据库查询到的详细信息"""
    merged_data = []

    for item in api_data:
        stock_code = item.get('代码')
        if stock_code and stock_code in stock_details:
            # 合并数据
            merged_item = { **stock_details[stock_code],**item}
            merged_data.append(merged_item)
            print(f"合并股票 {stock_code} 的数据成功")
        else:
            # 如果没有详细信息，只保留API数据
            merged_data.append(item)
            print(f"股票 {stock_code} 没有详细信息，仅保留API数据")

    return merged_data


def save_to_excel(data, output_file=None):
    """将合并后的数据保存到Excel文件（参考zjlx.py中的Excel处理）"""
    if not data:
        print("没有数据可保存")
        return None

    dateStamp = datetime.now().strftime("%Y%m%d")
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    output_dir = f"../spiltExcel/input/{dateStamp}"
    os.makedirs(output_dir, exist_ok=True)

    # 设置默认输出文件名 - 修改扩展名和目录
    if not output_file:
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        output_file = f"{output_dir}/qgqp_{dateStamp}.xlsx"

    try:
        # 创建DataFrame并筛选需要的列
        df = pd.DataFrame(data)

        # 筛选需要保留的列（按需求顺序排列）
        required_columns = [
            '排名', '名称', '综合得分', '机构参与度', '市盈率(动)','历史位置',
            '净利润同比(%)',  '年度涨幅(%)', '行业板块'
        ]

        # 处理列名映射（API和数据库可能使用不同列名）
        column_mapping = {
            '目前排名': '排名',
            '名称': '名称',  # 数据库中的"名称"对应"股票简称"
            '综合得分': '综合得分',  # API中的原始字段
            '机构参与度': '机构参与度',
            '市盈率(动)': '市盈率(动)',
            '历史位置': '历史位置',
            '净利润同比(%)': '净利润同比(%)',
            '年度涨幅(%)': '年度涨幅(%)',
            '行业板块': '行业板块'

        }
        # 综合得分 主力成本 市盈率(动) 年度涨幅(%) 转为数值后保留小数点后两位

        df['综合得分'] = df['综合得分'].astype(float).round(2)
        df['机构参与度'] = df['机构参与度'].astype(float).round(2)
        df['市盈率(动)'] = df['市盈率(动)'].astype(float).round(2)
        df['年度涨幅(%)'] = df['年度涨幅(%)'].astype(float).round(2)

        # 重命名列并筛选
        df = df.rename(columns=column_mapping)[required_columns]


        # 写入Excel文件并设置格式
        with ExcelWriter(output_file, engine='openpyxl') as writer:
            df.to_excel(writer, index=False, sheet_name='股票数据')

            # 获取工作表
            worksheet = writer.sheets['股票数据']

            # 设置列宽和行高
            for column in worksheet.columns:
                column_letter = openpyxl.utils.get_column_letter(column[0].column)
                worksheet.column_dimensions[column_letter].width = 18

            for i in range(1, worksheet.max_row + 1):
                worksheet.row_dimensions[i].height = 25

            # 设置字体和对齐方式（参考zjlx.py中的格式设置）
            font = Font(name='微软雅黑')
            alignment = Alignment(horizontal='center', vertical='center')

            # 创建黄色填充样式（用于表头）
            yellow_fill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')

            # 创建边框样式
            thin_border = Border(
                left=Side(style='thin'),
                right=Side(style='thin'),
                top=Side(style='thin'),
                bottom=Side(style='thin')
            )

            # 应用格式到所有单元格
            for row_idx, row in enumerate(worksheet.iter_rows()):
                for cell in row:
                    cell.alignment = alignment
                    cell.border = thin_border
                    cell.font = font

                    # 为表头设置黄色背景
                    if row_idx == 0:
                        cell.fill = yellow_fill

        print(f"Excel文件已生成: {output_file}")
        return output_file
    except Exception as e:
        print(f"保存Excel文件失败: {e}")
        return None


def main():
    """主函数：获取API数据，查询数据库，合并数据并保存到Excel"""
    try:
        input_json = "../json/response1.json"
        # 从API获取数据
        with open(input_json, 'r', encoding='utf-8') as f:
            data = json.load(f)

        if not data:
            print("未获取到API数据，程序终止")
            return
        stock_codes=[item['代码'] for item in data]

        # 从数据库查询股票详细信息
        stock_details = get_stock_details(stock_codes)

        # 合并数据
        merged_data = merge_data(data, stock_details)

        dateStamp = datetime.now().strftime("%Y%m%d")
        output_dir = f"../spiltExcel/input/{dateStamp}"
        os.makedirs(output_dir, exist_ok=True)


        # 设置默认输出文件名 - 修改扩展名和目录

        output_all_file = f"{output_dir}/qgqp_all_{dateStamp}.xlsx"
        output_top_file = f"{output_dir}/qgqp_top_{dateStamp}.xlsx"
        output_dtop_file = f"{output_dir}/qgqp_dtop_{dateStamp}.xlsx"

        merged_df = pd.DataFrame(merged_data)

        try:
            # 保存全部数据
            excel_file = save_to_excel(merged_data, output_all_file)

            # 获取前200条（按排名升序）
            merged_top_data = merged_df.sort_values(by='综合得分', ascending=False).head(200).to_dict('records')
            excel_file = save_to_excel(merged_top_data, output_top_file)

            # 获取后200条（按排名降序）
            merged_dtop_data = merged_df.sort_values(by='综合得分').head(200).to_dict('records')
            excel_file = save_to_excel(merged_dtop_data, output_dtop_file)

        except Exception as e:
            print(f"数据处理出错: {e}")



    except Exception as e:
        print(f"程序执行出错: {e}")


def process():
    main()


if __name__ == "__main__":
    main()
